package pay

import (
	"context"
	"sale-admin/config"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/logx"
	"github.com/go-pay/gopay"
	"github.com/go-pay/gopay/alipay"
)

type Alipay struct{}

var AlipayClient *alipay.Client

func (Alipay) ConfigInit(Appid, PrivateKey string) (err error) {

	// 初始化支付宝客户端
	//    appid：应用ID
	//    privateKey：应用私钥，支持PKCS1和PKCS8
	//    isProd：是否是正式环境
	client, err1 := alipay.NewClient(Appid, PrivateKey, true)
	if err1 != nil {
		logx.Error(context.Background(), "alipay config init error", logx.Any("err", err1.Error()))
		return
	}
	AlipayClient = client
	// Debug开关，输出/关闭日志
	AlipayClient.DebugSwitch = gopay.DebugOff

	// 配置公共参数
	AlipayClient.SetCharset("utf-8").
		SetSignType(alipay.RSA2).
		SetNotifyUrl(config.Config.AlipayNotifyUrl)

	// 自动同步验签（只支持证书模式）
	// 传入 alipayCertPublicKey_RSA2.crt 内容
	// AlipayClient.AutoVerifySign(cert.AlipayPublicContentRSA2)

	// 传入证书内容
	// err2 := AlipayClient.SetCertSnByContent(cert.AppPublicContent, cert.AlipayRootContent, cert.AlipayPublicContentRSA2)
	// 传入证书文件路径
	//err := client.SetCertSnByPath("cert/appCertPublicKey_2021000117673683.crt", "cert/alipayRootCert.crt", "cert/alipayCertPublicKey_RSA2.crt")
	// if err2 != nil {
	// logx.Error(context.Background(), "alipay config init error", logx.Any("SetCertSn Err", err.Error()))
	// return
	// }
	return
}

// 支付宝支付
func (Alipay) DoPay(outTradeNo string, PaymentAount float64) (rsp alipay.TradePrecreateResponse, err error) {
	// 请求参数
	bm := make(gopay.BodyMap)
	bm.Set("subject", "大道智创支付订单").
		Set("out_trade_no", outTradeNo).
		Set("total_amount", PaymentAount)

	// 创建订单
	aliRsp, err := AlipayClient.TradePrecreate(context.Background(), bm)
	if err != nil {
		if bizErr, ok := alipay.IsBizError(err); ok {
			logx.Error(context.Background(), "alipay dopay error", logx.Any("error", bizErr))
			return
		}
		return
	}

	// 同步返回验签
	// ok, err := alipay.VerifySyncSignWithCert(cert.AlipayPublicContentRSA2, aliRsp.SignData, aliRsp.Sign)
	// if err != nil {
	// 	xlog.Error(err)
	// }
	// xlog.Debug("同步返回验签：", ok)
	return *aliRsp, nil
}

type MicropayInitStruct struct {
	alipay.ErrorResponse
	RetCodeSub        string `json:"ret_code_sub"`
	RetMessageSub     string `json:"ret_message_sub"`
	ZimId             string `json:"zim_id"`
	ZimInitClientData string `json:"zim_init_client_data"`
}

type MicropayInitResponse struct {
	Response *MicropayInitStruct `json:"zoloz_authentication_smilepay_initialize_response"`
	Sign     string              `json:"sign"`
}

// 人脸支付初始化
// zoloz.authentication.smilepay.initialize 支付宝人脸支付初始化
func (Alipay) AliPayMicropayInit(MetaInfo interface{}) (rsp MicropayInitResponse, err error) {
	bm := make(gopay.BodyMap)

	// 自定义公共参数
	bm.Set("biz_content", MetaInfo)

	aliPsp := new(MicropayInitResponse)
	err1 := AlipayClient.PostAliPayAPISelfV2(context.Background(), bm, "zoloz.authentication.smilepay.initialize", aliPsp)
	if err1 != nil {
		logx.Error(context.Background(), "alipay micro pay init error", logx.Any("error", err1.Error()))
		return
	}
	return *aliPsp, nil
}

// 支付宝人脸支付
func (Alipay) AliPayMicropay(outTradeNo, authCode, payType string, PaymentAmount float64) (rsp alipay.TradePayResponse, err error) {
	// 请求参数
	bm := make(gopay.BodyMap)
	bm.Set("subject", "大道智创人脸支付").
		Set("scene", payType).
		Set("auth_code", authCode).
		Set("out_trade_no", outTradeNo).
		Set("total_amount", PaymentAmount).
		Set("timeout_express", "2m")

	aliRsp, err := AlipayClient.TradePay(context.Background(), bm)
	if err != nil {
		if bizErr, ok := alipay.IsBizError(err); ok {
			logx.Error(context.Background(), "alipay micro pay error", logx.Any("error", bizErr.Error()))
			return
		}
		return
	}
	return *aliRsp, nil
}

// 支付宝扫码枪支付

// 执行 -- 支付宝退款
func (Alipay) AliPayRefund(
	outTradeNo string,
	PaymentAmount float64, // 需要退款的金额。
	remark string,
	orderRefundNo string, // 退款单号 ,
) (
	rsp alipay.TradeRefundResponse,
	err error,
) {
	// 请求参数
	bm := make(gopay.BodyMap)
	bm.Set("out_trade_no", outTradeNo).
		Set("refund_amount", PaymentAmount).
		Set("refund_reason", remark).
		Set("out_request_no", orderRefundNo)

	// 发起退款请求
	aliRsp, err1 := AlipayClient.TradeRefund(context.Background(), bm)
	if err1 != nil {
		if bizErr, ok := alipay.IsBizError(err1); ok {
			logx.Error(context.Background(), "alipay refund error", logx.Any("error", bizErr.Error()))
			return
		}
		err = errorx.New("支付宝退款失败", -1)
		return *aliRsp, err
	}
	return *aliRsp, nil
}

// AliPayQuery 订单查询
func (Alipay) AliPayQuery(outTradeNo string) (rsp alipay.TradeQueryResponse, err error) {
	// 请求参数
	bm := make(gopay.BodyMap)
	bm.Set("out_trade_no", outTradeNo)

	aliRsp, err := AlipayClient.TradeQuery(context.Background(), bm)
	if err != nil {
		if bizErr, ok := alipay.IsBizError(err); ok {
			logx.Error(context.Background(), "alipay order query error", logx.Any("error", bizErr.Error()))
			return
		}
		return
	}
	return *aliRsp, nil
}

// AliPayClose 支付宝关闭订单
func (Alipay) AliPayClose(outTradeNo string) (rsp alipay.TradeCloseResponse, err error) {
	// 请求参数
	bm := make(gopay.BodyMap)
	bm.Set("out_trade_no", outTradeNo)

	aliRsp, err1 := AlipayClient.TradeClose(context.Background(), bm)
	if err1 != nil {
		if bizErr, ok := alipay.IsBizError(err1); ok {
			logx.Error(context.Background(), "alipay refund error", logx.Any("error", bizErr.Error()))
			return
		}
		err = errorx.New("支付宝关闭订单失败", -1)
		return *aliRsp, err
	}
	return *aliRsp, nil
}
